/* The file is saved in UTF-8 codepage.
 * Check: «Stereotype», Section mark-§, Copyright-©, Alpha-α, Beta-β, Smile-☺
 */
package cz.pecinovsky.english.lootp.manager;



////////////////////////////////////////////////////////////////////////////////
//%%+  +++++ End of ignored starting test - place for imports +++++

//%A+ >=133x
import cz.pecinovsky.english.lootp.utility.IO;
import cz.pecinovsky.english.lootp.utility.Position;

//%A-
//%X+ xxxxx Start of the ovejumped text with declaration of the envelope xxxxx
/*******************************************************************************
 *<pre>
 * Previous:  {@link cz.pecinovsky.english.lootp.shapes.Mover}
 * Following: Prozatím není
 *
 * Project 114z
 *         119:
 *    - Zdánlivě žádná změna,
 *      ale ve skutečnosti se používá jiné rozhraní IMoveable -
 *      to, které se nachází v tomto balíčku
 *
 * Project  125c - Přepravka
 *   ~ Změna deklarovaných metod v důsledku zavedení přepravek
 *
 * Projekt  133z - Balíčky
 *   + Přidány importy tříd a rozhraní přestěhovaných do jiných balíčků
 *</pre>
 *
 * @author Rudolf PECINOVSKÝ
 * @version 6.03.2017 — 2010-11-08
 */
////////////////////////////////////////////////////////////////////////////////
//%X- ----- End of the ovejumped text with declaration of the envelope -----


/*******************************************************************************
 * Instances of class {@code Mover} works as servants
 * continuously moving the served instances implementing the interface
 * {@link IMoveable}.
 *
 * @author Rudolf PECINOVSKÝ
 * @version 6.03.2017 — 2010-11-08
 */
public class Mover
{
//== CONSTANT CLASS ATTRIBUTES =================================================

    /** Number of miliseconds between moving and repainting object. */
    private static final int PERIOD = 50;



//== VARIABLE CLASS ATTRIBUTES =================================================

    /** Number of created instances. */
    private static int countCreated = 0;



//== STATIC CONSTRUCTOR (CLASS INITIALIZER, STATIC INICITALIZING BLOCK) ========
//== CONSTANT INSTANCE ATTRIBUTES ==============================================

    /** Instance ID = the order of the created instance inside its class. */
    private final int ID = ++countCreated;

    /** Name consisting from the class name and instance ID. */
    private final String name;



//== VARIABLE INSTANCE ATTRIBUTES ==============================================

    /** The speed of movement by this mover. */
    private int speed;



//== CLASS GETTERS AND SETTERS =================================================
//== OTHER NON-PRIVATE CLASS METHODS ===========================================

//##############################################################################
//== CONSTUCTORS AND FACTORY METHODS ===========================================

    /***************************************************************************
     * Creates a moover that moves the served objects with the default speed 1.
     */
    public Mover()
    {
        this(1);
    }


    /***************************************************************************
     * Creates a moover that moves the served objects with the specified speed.
     *
     * @param speed The speed that the mover uses for moving
     *              the served objects
     */
    public Mover(int speed)
    {
        if (speed <= 0) {
            throw new IllegalArgumentException(
                "The given speed must be positive!");
        }
        this.speed = speed;
        this.name  = getClass().getSimpleName() +
                     "[ID=" + ID + ", speed=" + speed + "]";
    }



//== ABSTRACT METHODS ==========================================================
//== INSTANCE GETTERS AND SETTERS ==============================================
//== OTHER NON-PRIVATE INSTANCE METHODS ========================================

    /***************************************************************************
     * Returns a string representation of the object (objects's signture).
     * It is used mainly by the debugging.
     *
     * @return  Simple class name followed by brackets
     *          with instance ID and speed
     */
    @Override
    public String toString()
    {
        return name;
    }


    /***************************************************************************
     * Continuously moves the specified object
     * by the specified number of points.
     *
     * @param right   Number of points moving to the right
     * @param down    Number of points moving down
     * @param object  The moved object
     */
    public void moveBy(int right, int down, IMoveable object)
    {
        double distance = Math.sqrt(right*right + down*down);
        int    step     = (int)(distance / speed);
        double dx = (right+.4) / step;
        double dy = (down   +.4) / step;
//%I+ <125
//        int    px = object.getX();
//        int    py = object.getY();
//        double x  = px + .4;
//        double y  = py + .4;
//%I-
//%A+ >125
        Position pozice = object.getPosition();
        double   x      = pozice.x + .4;
        double   y      = pozice.y + .4;
//%A-

        for (int i=step;   i > 0;   i--) {
            x = x + dx;
            y = y + dy;
            object.setPosition((int)x, (int)y);
            IO.pause(PERIOD);
        }
    }

//%A+ >125

    /***************************************************************************
     * Continuously moves the specified object
     * by the specified number of points.
     *
     * @param distance  Number of points for moving
     * @param object  The moved object
     */
    public void moveBy(Position distance, IMoveable object)
    {
        moveBy(distance.x, distance.y, object);
    }

//%A-

    /***************************************************************************
     * Continuously moves the given object to given position.
     *
     * @param x       x coordinate of the requiered destination position
     * @param y       y coordinate of the requiered destination position
     * @param object  The moved object
     */
    public void moveTo(int x, int y, IMoveable object)
    {
//%I+ <125
//        int px = object.getX();
//        int py = object.getY();
//        moveBy(x-px, y-py, object);
//%I-
//%A+ >125
        Position position = object.getPosition();
        moveBy(x-position.x, y-position.y, object);
//%A-
    }

//%A+ >125

    /***************************************************************************
     * Continuously moves the given object to given position.
     *
     * @param position The destination position
     * @param object   The moved object
     */
    public void moveTo(Position position, IMoveable object)
    {
        moveTo(position.x, position.y, object);
    }

//%A-


//== PRIVATE AND AUXILIARY CLASS METHODS =======================================
//== PRIVATE AND AUXILIARY INSTANCE METHODS ====================================
//== EMBEDDED TYPES AND INNER CLASSES ==========================================
//== TESTING CLASSES AND METHODS ===============================================
}
